package com.qhgrain.app.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.paas.base.modules.utils.lang.StringUtil;
import com.qhgrain.app.constant.UrlEnum;
import com.qhgrain.app.service.ApplicationService;
import com.qhgrain.app.service.MenuService;
import com.qhgrain.app.service.PermissionService;
import com.qhgrain.app.util.ConfigUtil;
import com.qhgrain.app.vo.MenuVo;
import com.qhgrain.app.vo.PairVo;
import com.qhgrain.app.vo.PermissionVo;
import com.qhgrain.gway.util.HttpUtil;

@Controller
@RequestMapping("/menu")
public class MenuController {

	private static Logger LOG = LoggerFactory.getLogger(MenuController.class);
	
	@Autowired
	private ApplicationService applicationService;
	
	@Autowired
	private PermissionService permissionService;
	
	
	static String serverUrl = ConfigUtil.getProperties(UrlEnum.MENU_ROLE_PERMISSION)+"/menu";
	
	static String serverUrl2 = ConfigUtil.getProperties(UrlEnum.MENU_ROLE_PERMISSION)+"/permission";
	
	
	@Autowired
	private MenuService menuService;
	
	@RequiresPermissions({"common-service-menu:query"} )
	@RequestMapping(value="/index")
	public String index(Model model){
		model.addAttribute("title","菜单管理");
		model.addAttribute("menu", new MenuVo());
		model.addAttribute("appList",getAppList());
		model.addAttribute("currentTime",new Date().getTime());
		return "menu/menu_index";
	}
	
	@RequestMapping(value="/query/menus/{appId}")
	@ResponseBody
	public JSONObject queryMenus(Model model,@PathVariable String appId){
		JSONObject result = new JSONObject();
		try {
			
			//如果是超级管理员，不需要传userId, 如果不是，则传userId
			//map.put("userId", "");
			//菜单状态，这里不需要传
			JSONArray menusArray = menuService.getAll(appId, null, null);
			
			result.put("code", "success");
			result.put("data", menusArray);
			
		} catch (Exception e) {
			LOG.error("根据appId获取菜单报错。。。",e);
			result.put("code", "fail");
		}
		
		return result;
	}
	@RequestMapping(value="/get/menu/{menuId}")
	public String getMenu(Model model,@PathVariable String menuId){
		try {
			//页面虚拟id“0”，用于清除界面数据
			if("0".equals(menuId)){
				model.addAttribute("menu", new MenuVo());
			}else{
				JSONObject menu = getMenu(menuId);
				if(menu != null){
					String parentMenuId = menu.getString("parentMenuId");
					if(StringUtil.isNotBlank(parentMenuId)){
						model.addAttribute("parentMenuList", getAllParentMenus(menuId));
						model.addAttribute("parentMenu",getMenu(parentMenuId));
					}
					
					model.addAttribute("menu", menu);
				}else{
					LOG.error("根据menuId从api获取数据失败");
					model.addAttribute("menu", new MenuVo());
				}
			}
		} catch (Exception e) {
			LOG.error("根据menuId获取对象系统出错...",e);
		}
		model.addAttribute("title","菜单管理");
		model.addAttribute("currentTime",new Date().getTime());
		return "menu/menu_edit";
	}
	
	private JSONArray getAllParentMenus(String menuId){
		//获取所有父级菜单
		String vo2;
		try {
			vo2 = HttpUtil.get(serverUrl+"/query/parent/menus/"+menuId.trim(), new HashMap<String,String>());
			JSONObject voJson2 = JSONObject.parseObject(vo2);
			if("1".equals(voJson2.getString("state"))){
				return voJson2.getJSONArray("data");
			}
		} catch (IOException e) {
			LOG.error("根据菜单id获取所有父级菜单，失败...",e);
		}
		
		return new JSONArray();
	}
	
	private JSONArray getAllChildMenus(String menuId) throws IOException{
		//获取所有下级菜单
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("menuId", menuId);
//		map.put("userId", userId);
//		map.put("status", status);
		map.put("isQueryAll", "true");
		String vo2 = HttpUtil.postFormParams(serverUrl, "/query/child/menus", map);
		JSONObject voJson2 = JSONObject.parseObject(vo2);
		if("1".equals(voJson2.getString("state"))){
			return voJson2.getJSONArray("data");
		}
		return new JSONArray();
	}
	
	private JSONObject getMenu(String menuId){
		String vo;
		try {
			vo = HttpUtil.get(serverUrl+"/get/"+menuId.trim(), new HashMap<String,String>());
			JSONObject voJson = JSONObject.parseObject(vo);
			if("1".equals(voJson.getString("state"))){
				return voJson.getJSONObject("data");
			}else{
				LOG.error("根据menuId从api获取数据失败"+vo);
			}
		} catch (IOException e) {
			LOG.error("根据menuId获取数据失败",e);
		}
		
		return null;
	}
	
	@RequestMapping(value="/save")
	@ResponseBody
	public JSONObject save(Model model,String menuId,String parentMenuId,String menuName,String menuUrl,String menuOrderNum,String menuStatus,String appId){
		JSONObject result = new JSONObject();
		try {
			if(StringUtil.isBlank(appId) || StringUtil.isBlank(menuName) || StringUtil.isBlank(menuStatus)){
				result.put("code", "1");
				result.put("msg", "必要参数不能为空");
			}else{
				Map<String,Object> map = new HashMap<String,Object>();
				map.put("menuName", menuName.trim());
				map.put("menuUrl", menuUrl);
				map.put("parentMenuId", parentMenuId);
				map.put("appId", appId);
				map.put("status", menuStatus);
				map.put("orderNum", menuOrderNum);
				
				String vo ;
				if(StringUtil.isNotBlank(menuId)){
					// 修改
					map.put("menuId", menuId.trim());
					vo = HttpUtil.postFormParams(serverUrl, "/edit", map);
				}else{
					//新增
					vo = HttpUtil.postFormParams(serverUrl, "/add", map);
				}
				JSONObject voJson = JSONObject.parseObject(vo);
				if("1".equals(voJson.getString("state"))){
					
					//新增菜单同时新增菜单对应的菜单权限（非必要成功操作）
					if(StringUtil.isBlank(menuId)){
						try{
							map = new HashMap<String,Object>();
							map.put("name", menuName.trim()+"-菜单权限");
							map.put("type", "0"); //菜单权限
							map.put("menuId", voJson.get("data"));
							map.put("pvalue", voJson.get("data"));
							map.put("description", menuName.trim()+"-菜单权限");
							vo = HttpUtil.postFormParams(serverUrl2, "/add", map);
						}catch (Exception e){
							LOG.error("新增菜单，同时新增菜单权限，api失败....",e);
						}
					}
					result.put("code", "0");
					result.put("msg", "成功");
				}else{
					result.put("code", "2");
					result.put("msg", "保存失败");
					LOG.error("保存菜单信息，api失败..."+vo);
				}
			}
		} catch (Exception e) {
			LOG.error("保存菜单信息系统错误...",e);
			result.put("code", "2");
		}
		return result;
	}
	@RequestMapping(value="/add/same/level/page")
	public String addSameLevel(Model model, String menuId,String parentMenuId){
		model.addAttribute("title","增加同级菜单");
		MenuVo menu = new MenuVo();
		menu.setParentMenuId(parentMenuId);
		if(StringUtil.isNotBlank(parentMenuId)){
			model.addAttribute("parentMenuList", getAllParentMenus(menuId));
		}
		model.addAttribute("backMenuId", menuId);
		model.addAttribute("menu", menu);
		return "menu/menu_edit";
		
	}
	@RequestMapping(value="/add/next/level/page")
	public String addNextLevel(Model model, String menuId){
		model.addAttribute("title","增加同级菜单");
		MenuVo menu = new MenuVo();
		menu.setParentMenuId(menuId);
		//构建父菜单路径
		JSONArray array = getAllParentMenus(menuId);
		array.add(getMenu(menuId));
		model.addAttribute("parentMenuList", array);
		model.addAttribute("backMenuId", menuId);
		model.addAttribute("menu", menu);
		return "menu/menu_edit";
	}
	
	@RequestMapping(value="/get/child/count")
	@ResponseBody
	public JSONObject getChildMenuCount(Model model,String menuId,String status){
		JSONObject result = new JSONObject();
		JSONArray array;
		try {
			array = getAllChildMenus(menuId);
			JSONArray list = new JSONArray();
			JSONObject t;
			for(int i=0;i<array.size();i++){
				t = array.getJSONObject(i);
				if(status.equals(t.getString("status"))){
					list.add(t);
				}
			}
			result.put("code", "success");
			result.put("count", list.size());
		} catch (IOException e) {
			LOG.error("获取所有子菜单系统出错...",e);
			result.put("code", "fail");
		}
		return result;
	}
	@RequestMapping(value="/stop/{menuId}")
	@ResponseBody
	public JSONObject stopMenu(Model model,@PathVariable String menuId){
		return updateStatus(menuId,"1",true);
	}
	@RequestMapping(value="/open/{menuId}")
	@ResponseBody
	public JSONObject openMenu(Model model,@PathVariable String menuId){
		return updateStatus(menuId,"0",false);
	}
	@RequestMapping(value="/delete/{menuId}")
	@ResponseBody
	public JSONObject deleteMenu(Model model,@PathVariable String menuId){
		JSONObject result = new JSONObject();
		List<String> ids = new ArrayList<String>();
		ids.add(menuId);
		
		try {
			JSONArray childs = getAllChildMenus(menuId);
			for(int i=0;i<childs.size();i++){
				ids.add(childs.getJSONObject(i).getString("id"));
			}
			
			String idsString = StringUtils.join(ids, ",");
			Map<String,Object> map = new HashMap<String,Object>();
			map.put("menuIds", idsString);
			
			String vo = HttpUtil.postFormParams(serverUrl, "/delete", map);
			JSONObject voJson = JSONObject.parseObject(vo);
			if("1".equals(voJson.getString("state"))){
				//删除菜单同时删除菜单对应的菜单权限（非必要成功操作）
				try{
					JSONArray perArray = this.permissionService.queryByMenuIds(Arrays.asList(menuId));
					List<PermissionVo> permissions = JSONArray.parseArray(perArray.toJSONString(), PermissionVo.class);
					for(PermissionVo p : permissions){
						if("0".equals(p.getType())){
							map= new HashMap<String,Object>();
							map.put("ids", p.getId());
							vo = HttpUtil.postFormParams(serverUrl, "/delete", map);
						}
					}
				}catch (Exception e){
					e.printStackTrace();
				}
				result.put("code", "success");
			}else{
				result.put("code", "fail");
				LOG.error("删除菜单，api更新出错..."+vo);
			}
		} catch (IOException e) {
			result.put("code", "fail");
			LOG.error("删除菜单系统出错...",e);
		}
		return result;
	}
	
	/**
	 * 级联更改菜单状态
	 * @param menuId
	 * @param status
	 * @return
	 */
	private JSONObject updateStatus(String menuId,String status,boolean isNeedEditChild){
		JSONObject result = new JSONObject();
		List<String> ids = new ArrayList<String>();
		ids.add(menuId);
		
		try {
			if(isNeedEditChild){
				JSONArray childs = getAllChildMenus(menuId);
				for(int i=0;i<childs.size();i++){
					ids.add(childs.getJSONObject(i).getString("id"));
				}
			}
			String idsString = StringUtils.join(ids, ",");
			Map<String,Object> map = new HashMap<String,Object>();
			map.put("menuIds", idsString);
			map.put("status", status);
			
			String vo = HttpUtil.postFormParams(serverUrl, "/update/status", map);
			JSONObject voJson = JSONObject.parseObject(vo);
			if("1".equals(voJson.getString("state"))){
				result.put("code", "success");
			}else{
				result.put("code", "fail");
				LOG.error("禁用/启用菜单，api更新出错..."+vo);
			}
		} catch (IOException e) {
			result.put("code", "fail");
			LOG.error("禁用/启用菜单系统出错...",e);
		}
		return result;
	}
	private List<PairVo> getAppList(){
		/*List<PairVo> list = new ArrayList<PairVo>();
		list.add(new PairVo("1","应用1"));
		list.add(new PairVo("2","应用2"));
		list.add(new PairVo("3","应用3"));
		
		
		return list;*/
		try {
			return applicationService.getAll(null);
		} catch (Exception e) {
			LOG.error("获取所有APP时报错....",e);
			return new ArrayList<PairVo>();
		}
	}
}
